/*
	GadgetArmor.cpp
	(c)2000 Palestar, Richard Lyle
*/


#include "Debug/Assert.h"
#include "GadgetArmor.h"
#include "GameContext.h"

//----------------------------------------------------------------------------

IMPLEMENT_ABSTRACT_FACTORY( GadgetArmor, NounGadget ); 
REGISTER_FACTORY_KEY( GadgetArmor, 4137179553683648623 );

BEGIN_ABSTRACT_PROPERTY_LIST( GadgetArmor, NounGadget );
	ADD_TRANSMIT_UPDATE_PROPERTY( m_Armor );
END_PROPERTY_LIST();

GadgetArmor::GadgetArmor() : m_Armor( 0 ), m_fModifier( 1.0f ), m_nArmorTick( 0 )
{}

//----------------------------------------------------------------------------

void GadgetArmor::setup()
{
	NounGadget::setup();
	// start out at full strength
	m_Armor = maxArmor();
}

void GadgetArmor::simulate( dword nTick )
{
	if ( nTick >= m_nArmorTick )
	{
		m_nArmorTick = nTick + TICKS_PER_SECOND;
		// repair the armor
		int nMax = maxArmor();
		if ( m_Armor < nMax )
			m_Armor = Clamp( m_Armor + repairRate(), 0, nMax );
	}

	NounGadget::simulate( nTick );
}

//----------------------------------------------------------------------------

NounGadget::Type GadgetArmor::type() const
{
	return ARMOR;
}

NounGadget::EnergyClass GadgetArmor::energyClass() const
{
	return ENERGY_CLASS_DEFENSE;
}

CharString GadgetArmor::status() const
{
	return CharString().format("%d%%", ((armor() * 100) / maxArmor()) );
}

float GadgetArmor::addMass() const
{
	return maxArmor() / 60000.0f;
}

bool GadgetArmor::canDamage( dword type ) const
{
	return false;
}

bool GadgetArmor::needRepair( Noun * pWhom ) const
{
	if ( NounGadget::needRepair(pWhom) )
		return true;
	return armor() < maxArmor();
}

//----------------------------------------------------------------------------

bool GadgetArmor::repair( Noun * pWhom, int nDamage )
{
	// repair the armor
	m_Armor = Clamp( m_Armor + nDamage, 0, maxArmor() );
	return m_Armor < maxArmor();
}

void GadgetArmor::setArmor( int armor )
{
	m_Armor = Clamp( armor, 0, maxArmor() );
}

void GadgetArmor::setModifier( float fModifier )
{
	m_fModifier = fModifier;
}

int GadgetArmor::deflect( dword nType, int damage, Facing nFacing )
{
	if ( !canDeflect( nType ) )
		return damage;	// doesn't deflect this type of damage
	if ( (facingMountFlags( nFacing ) & mountFlags()) == 0 )
		return damage;	// wrong facing

	float fMod = damageModifier( nType );
	if ( fMod <= 0.0f )
		return 0;		// full damage reflected!	

	int nModifiedDamage = fMod * damage;
	int nDeflected = Min( nModifiedDamage, m_Armor );
	m_Armor -= nDeflected;
	if ( m_Armor > 0 )
		return 0;		// full damage is deflected...

	// return the un-modified damage value..
	return damage - (nDeflected / fMod);
}

//----------------------------------------------------------------------------
// EOF
